---
title: Bar
---

Bar charts renders a dataset as series of bars and is used for comparing numeric values between different categories.

## Basic

See the [full API here](/docs/api/victory-bar). Typically composed with [`VictoryChart`](/docs/api/victory-chart) to create full charts.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar data={sampleData} />
</VictoryChart>
```

## Bar Charts - Domain

Bars in `VictoryBar` are centered around their corresponding value by default. You can move your bars away from your axis by setting a new domain, adding `domainPadding`, or changing how bars are aligned relative to their values with the `alignment` prop on `VictoryBar`.

:::note
Using `domainPadding` to adjust the bar position is the most common way to adjust the position of bars in a chart.
:::

```jsx live
<VictoryChart
  domainPadding={{ x: 50 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar data={sampleData} />
</VictoryChart>
```

:::note
Setting the bar alignment using the `alignment` prop.
:::

```jsx live
<VictoryChart
  theme={VictoryTheme.clean}
>
  <VictoryBar
    alignment="start"
    data={sampleData}
  />
</VictoryChart>
```

:::note
Setting the bar alignment using the `domain` prop.
:::

```jsx live
<VictoryChart
  domain={{ x: [0.5, 5.5] }}
  theme={VictoryTheme.clean}
>
  <VictoryBar data={sampleData} />
</VictoryChart>
```

## Bar Charts - Horizontal

Bar charts can be rendered horizontally by setting the `horizontal` prop to `true`. This prop can be applied to either `VictoryChart` or `VictoryBar`.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  horizontal
  theme={VictoryTheme.clean}
>
  <VictoryBar />
</VictoryChart>
```

## Bar Charts - Labels

Add labels to charts by setting the `labels` prop to the name of a property in the dataset, or a function that returns the label value. You can customize the display of the labels by using the [`labelComponent`](/docs/api/victory-area#labelcomponent) prop.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar
    data={sampleData}
    labels={({ datum }) => datum.y}
  />
</VictoryChart>
```

## Bar Charts - Tooltips

Tooltips can be added by using a [`VictoryTooltip`](/docs/api/victory-tooltip) component as the `labelComponent`.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar
    data={sampleData}
    labelComponent={<VictoryTooltip />}
    labels={({ datum }) => datum.y}
  />
</VictoryChart>
```

## Bar Charts - Grouped

Bar charts can be grouped to show how different subcategories compare to each other.

```jsx live noInline
function App() {
  return (
    <VictoryChart
      theme={VictoryTheme.clean}
      domain={{ y: [0.5, 5.5] }}
      domainPadding={{ x: 40 }}
    >
      <VictoryGroup
        offset={20}
        style={{ data: { width: 15 } }}
      >
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 1 },
            { x: "2023 Q2", y: 2 },
            { x: "2023 Q3", y: 3 },
            { x: "2023 Q4", y: 2 },
          ]}
        />
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 2 },
            { x: "2023 Q2", y: 3 },
            { x: "2023 Q3", y: 4 },
            { x: "2023 Q4", y: 5 },
          ]}
        />
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 1 },
            { x: "2023 Q2", y: 2 },
            { x: "2023 Q3", y: 3 },
            { x: "2023 Q4", y: 4 },
          ]}
        />
      </VictoryGroup>
    </VictoryChart>
  );
}

render(<App />);
```

## Bar Charts - Grouped Labels

Bar chart labels for grouped bars can be rendered by setting the `labels` prop to the name of a property in the dataset, an array, or a function that returns the label value.

```jsx live noInline
function App() {
  return (
    <VictoryChart
      theme={VictoryTheme.clean}
      domain={{ y: [0.5, 5.5] }}
      domainPadding={{ x: 40 }}
    >
      <VictoryGroup
        offset={20}
        style={{ data: { width: 15 } }}
      >
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 1 },
            { x: "2023 Q2", y: 2 },
            { x: "2023 Q3", y: 3 },
            { x: "2023 Q4", y: 2 },
          ]}
          labels={({ datum }) =>
            datum.y
          }
        />
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 2 },
            { x: "2023 Q2", y: 3 },
            { x: "2023 Q3", y: 4 },
            { x: "2023 Q4", y: 5 },
          ]}
          labels={({ datum }) =>
            datum.y
          }
        />
        <VictoryBar
          data={[
            { x: "2023 Q1", y: 1 },
            { x: "2023 Q2", y: 2 },
            { x: "2023 Q3", y: 3 },
            { x: "2023 Q4", y: 4 },
          ]}
          labels={({ datum }) =>
            datum.y
          }
        />
      </VictoryGroup>
    </VictoryChart>
  );
}

render(<App />);
```

## Bar Charts - Combination

Bar charts can be rendered with other chart types like `Line`.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  horizontal
  theme={VictoryTheme.clean}
>
  <VictoryBar />
  <VictoryLine />
</VictoryChart>
```

## Bar Charts - Animation

Charts can be animated by setting the `animate` prop. See the [animations](/docs/guides/animations) guide for more information.

```jsx live noInline
function App() {
  const [data, setData] =
    React.useState(getData());

  React.useState(() => {
    const setStateInterval =
      window.setInterval(() => {
        setData(getData());
      }, 4000);

    return () => {
      window.clearInterval(
        setStateInterval,
      );
    };
  }, []);

  return (
    <VictoryChart
      theme={VictoryTheme.clean}
      domainPadding={{ x: 20 }}
    >
      <VictoryBar
        animate={{ duration: 1000 }}
        data={data}
      />
    </VictoryChart>
  );
}

function getData() {
  return [
    { x: 1, y: _.random(1, 5) },
    { x: 2, y: _.random(1, 10) },
    { x: 3, y: _.random(2, 10) },
    { x: 4, y: _.random(2, 10) },
    { x: 5, y: _.random(2, 15) },
    { x: 6, y: _.random(2, 8) },
    { x: 7, y: _.random(2, 11) },
  ];
}

render(<App />);
```

## Bar Charts - Zoom & Pan

Bar charts support pan and zoom behavior by using the `VictoryZoomContainer` component. See the [Pan & Zoom](/docs/guides/pan-and-zoom) guide for more information.

```jsx live
<VictoryChart
  domain={{ x: [0, 10] }}
  theme={VictoryTheme.clean}
  containerComponent={
    <VictoryZoomContainer
      zoomDimension="x"
      zoomDomain={{ x: [0, 5] }}
      minimumZoom={{ x: 1 }}
    />
  }
>
  <VictoryBar
    data={[
      { x: 1, y: 2 },
      { x: 2, y: 3 },
      { x: 3, y: 5 },
      { x: 4, y: 4 },
      { x: 5, y: 7 },
      { x: 6, y: 6 },
      { x: 7, y: 8 },
      { x: 8, y: 9 },
      { x: 9, y: 10 },
      { x: 10, y: 12 },
    ]}
  />
</VictoryChart>
```

## Bar Charts - Styles

Chart styling can be customized by using the theme or overriding the style prop on the component.

```jsx live
<VictoryChart
  domainPadding={{ x: 20 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar
    data={sampleData}
    labels={({ datum }) => datum.y}
    style={{
      data: {
        fill: "#c43a31",
        fillOpacity: 0.4,
        stroke: "#c43a31",
        strokeWidth: 2,
      },
      labels: {
        fontSize: 12,
        fill: "#c43a31",
      },
    }}
  />
</VictoryChart>
```

## Bar Charts - Events

Events can be handled by passing an array of event objects to the `events` prop on the component. Each event object should specify a `target` and an `eventHandlers` object. See the [events](/docs/guides/events) guide for more information.

```jsx live noInline
function App() {
  const toggleFillColor = (fill) => {
    if (fill === "black") {
      return null;
    } else {
      return {
        style: {
          fill: "black",
        },
      };
    }
  };

  return (
    <VictoryChart
      domainPadding={{ x: 20 }}
      theme={VictoryTheme.clean}
    >
      <VictoryBar
        data={sampleData}
        labels={({ datum }) => datum.y}
        events={[
          {
            target: "data",
            eventHandlers: {
              onClick: () => {
                return [
                  {
                    target: "data",
                    mutation: (props) =>
                      toggleFillColor(
                        props.style
                          ?.fill,
                      ),
                  },
                ];
              },
            },
          },
        ]}
      />
    </VictoryChart>
  );
}

render(<App />);
```

## Stacked Bar Charts

Bar charts can be stacked to show how different categories contribute to the total.

```jsx live
<VictoryChart
  domainPadding={{ x: 40 }}
  theme={VictoryTheme.clean}
>
  <VictoryStack>
    <VictoryBar
      data={[
        { x: "Sales", y: 2 },
        { x: "Marketing", y: 3 },
        { x: "Finance", y: 5 },
      ]}
    />
    <VictoryBar
      data={[
        { x: "Sales", y: 1 },
        { x: "Marketing", y: 4 },
        { x: "Finance", y: 5 },
      ]}
    />
    <VictoryBar
      data={[
        { x: "Sales", y: 3 },
        { x: "Marketing", y: 2 },
        { x: "Finance", y: 6 },
      ]}
    />
  </VictoryStack>
</VictoryChart>
```

## Stacked Bar Charts - 100%

While Victory does not support 100% stacked bar charts natively, you can achieve this by transforming your data.

```jsx live noInline
const myDataset = [
  [
    { x: "a", y: 1 },
    { x: "b", y: 2 },
    { x: "c", y: 3 },
    { x: "d", y: 2 },
    { x: "e", y: 3 },
  ],
  [
    { x: "a", y: 2 },
    { x: "b", y: 3 },
    { x: "c", y: 7 },
    { x: "d", y: 5 },
    { x: "e", y: 3 },
  ],
  [
    { x: "a", y: 5 },
    { x: "b", y: 2 },
    { x: "c", y: 3 },
    { x: "d", y: 4 },
    { x: "e", y: 4 },
  ],
];

function App() {
  // This is an example of a function you might
  // use to transform your data to make 100% data

  function transformData(dataset) {
    const totals = dataset[0].map(
      (data, i) => {
        return dataset.reduce(
          (memo, curr) => {
            return memo + curr[i].y;
          },
          0,
        );
      },
    );
    return dataset.map((data) => {
      return data.map((datum, i) => {
        return {
          x: datum.x,
          y:
            (datum.y / totals[i]) * 100,
        };
      });
    });
  }

  const dataset =
    transformData(myDataset);
  return (
    <div>
      <VictoryChart
        domainPadding={{ x: 30, y: 20 }}
        theme={VictoryTheme.clean}
      >
        <VictoryStack>
          {dataset.map((data, i) => {
            return (
              <VictoryBar
                data={data}
                key={i}
              />
            );
          })}
        </VictoryStack>
        <VictoryAxis
          dependentAxis
          tickFormat={(tick) =>
            `${tick}%`
          }
        />
        <VictoryAxis
          tickFormat={[
            "a",
            "b",
            "c",
            "d",
            "e",
          ]}
        />
      </VictoryChart>
    </div>
  );
}

render(<App />);
```

## Stacked Bar Charts - Grouped

Bar charts can be stacked and grouped to show how different subcategories contribute to the total.

```jsx live noInline
function App() {
  const getBarData = () => {
    return [1, 2, 3, 4, 5].map(() => {
      return [
        { x: 1, y: Math.random() },
        { x: 2, y: Math.random() },
        { x: 3, y: Math.random() },
      ];
    });
  };

  return (
    <div>
      <VictoryChart
        domainPadding={{ x: 50 }}
      >
        <VictoryGroup
          offset={20}
          style={{
            data: { width: 15 },
          }}
        >
          <VictoryStack
            colorScale={"red"}
          >
            {getBarData().map(
              (data, index) => {
                return (
                  <VictoryBar
                    key={index}
                    data={data}
                  />
                );
              },
            )}
          </VictoryStack>
          <VictoryStack
            colorScale={"green"}
          >
            {getBarData().map(
              (data, index) => {
                return (
                  <VictoryBar
                    key={index}
                    data={data}
                  />
                );
              },
            )}
          </VictoryStack>
          <VictoryStack
            colorScale={"blue"}
          >
            {getBarData().map(
              (data, index) => {
                return (
                  <VictoryBar
                    key={index}
                    data={data}
                  />
                );
              },
            )}
          </VictoryStack>
        </VictoryGroup>
      </VictoryChart>
    </div>
  );
}

render(<App />);
```

## Diverging Bar Charts

Diverging bar are useful for showing how different categories compare to a common baseline. By default, Victory will calculate the domain based on the data provided.

```jsx live
<VictoryChart
  domainPadding={{ x: 50 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar
    data={[
      { x: "rabbits", y: 5 },
      { x: "cats", y: -10 },
      { x: "dogs", y: 15 },
      { x: "turtles", y: -8 },
      { x: "snakes", y: -2 },
      { x: "fish", y: 5 },
    ]}
  />
</VictoryChart>
```

## Diverging Bar Charts - Horizontal

Diverging bar are useful for showing how different categories compare to a common baseline. By default, Victory will calculate the domain based on the data provided.

```jsx live
<VictoryChart
  horizontal
  domainPadding={{ x: 50 }}
  theme={VictoryTheme.clean}
>
  <VictoryBar
    data={[
      { x: "rabbits", y: 5 },
      { x: "cats", y: -10 },
      { x: "dogs", y: 15 },
      { x: "turtles", y: -8 },
      { x: "snakes", y: -2 },
      { x: "fish", y: 5 },
    ]}
  />
</VictoryChart>
```

## Diverging Bar Charts - Grouped

Diverging bar are useful for showing how different categories compare to a common baseline. By default, Victory will calculate the baseline based on the data provided.

```jsx live noInline
function App() {
  return (
    <VictoryChart
      domainPadding={{ x: 50 }}
      theme={VictoryTheme.clean}
    >
      <VictoryGroup
        offset={18}
        colorScale={"qualitative"}
      >
        {getBarData().map(
          (data, index) => {
            return (
              <VictoryBar
                key={index}
                data={data}
                labels={({ datum }) =>
                  datum.y
                }
              />
            );
          },
        )}
      </VictoryGroup>
    </VictoryChart>
  );
}

function getBarData() {
  return _.range(5).map(() => {
    return [
      {
        x: "rabbits",
        y: _.random(-5, 5),
      },
      {
        x: "cats",
        y: _.random(-10, 10),
      },
      {
        x: "dogs",
        y: _.random(-15, 15),
      },
    ];
  });
}

render(<App />);
```

## Diverging Bar Charts - Floating

Diverging bar are useful for showing how different categories compare to a common baseline.

```jsx live noInline
const dataA = [
  { x: "Television", y: 38 },
  { x: "Smartwatch", y: 37 },
  { x: "Fitness Monitor", y: 25 },
  { x: "Tablet", y: 19 },
  { x: "Camera", y: 15 },
  { x: "Laptop", y: 13 },
  { x: "Phone", y: 12 },
];

const dataB = dataA.map((point) => {
  const y = Math.round(
    point.y +
      3 * (Math.random() - 0.75),
  );
  return { ...point, y };
});

const width = 400;
const height = 300;

function App() {
  return (
    <VictoryChart
      horizontal
      height={height}
      width={width}
      padding={{
        top: 100,
        bottom: 30,
        left: 50,
        right: 50,
      }}
      theme={VictoryTheme.clean}
    >
      <VictoryLegend
        x={90}
        y={20}
        orientation="horizontal"
        gutter={20}
        data={[
          {
            name: "Ages 18-20",
          },
          {
            name: "Ages 21-24",
          },
        ]}
      />
      <VictoryStack
        style={{
          data: { width: 12 },
          labels: { fontSize: 12 },
        }}
      >
        <VictoryBar
          data={dataA}
          y={(data) =>
            -Math.abs(data.y)
          }
          labels={({ datum }) =>
            `${Math.abs(datum.y)}%`
          }
        />
        <VictoryBar
          data={dataB}
          labels={({ datum }) =>
            `${Math.abs(datum.y)}%`
          }
        />
      </VictoryStack>

      <VictoryAxis
        style={{
          axis: {
            stroke: "transparent",
          },
          ticks: {
            stroke: "transparent",
          },
          tickLabels: {
            fontSize: 12,
            fill: "black",
          },
        }}
        /*
          Use a custom tickLabelComponent with
          an absolutely positioned x value to position
          your tick labels in the center of the chart. The correct
          y values are still provided by VictoryAxis for each tick
        */
        tickLabelComponent={
          <VictoryLabel
            x={width / 2}
            textAnchor="middle"
          />
        }
        tickValues={dataA
          .map((point) => point.x)
          .reverse()}
      />
    </VictoryChart>
  );
}

render(<App />);
```

## Polar Bar Charts

Bar charts can be rendered in polar coordinates by setting the `polar` prop to `true` and using `VictoryPolarAxis` components.

```jsx live
<VictoryChart
  polar
  theme={VictoryTheme.clean}
>
  <VictoryPolarAxis
    dependentAxis
    style={{ axis: { stroke: "none" } }}
    tickFormat={() => null}
  />
  <VictoryPolarAxis />
  <VictoryBar data={sampleData} />
</VictoryChart>
```

## Polar Bar Charts - Stacked

Bar charts can be rendered in polar coordinates by setting the `polar` prop to `true` and using `VictoryPolarAxis` components.

```jsx live noInline
const directions = {
  0: "E",
  45: "NE",
  90: "N",
  135: "NW",
  180: "W",
  225: "SW",
  270: "S",
  315: "SE",
};
const orange = {
  base: "#2D7FF9",
  highlight: "#2750AE",
};
const red = {
  base: "#8B46FF",
  highlight: "#6B1CB0",
};
const innerRadius = 30;

function CompassCenter(props) {
  const { origin } = props;
  const circleStyle = {
    stroke: red.base,
    strokeWidth: 2,
    fill: orange.base,
  };

  return (
    <g>
      <circle
        cx={origin.x}
        cy={origin.y}
        r={innerRadius}
        style={circleStyle}
      />
    </g>
  );
}

function CenterLabel(props) {
  const { datum, active, color } =
    props;
  const text = [
    `${directions[datum._x]}`,
    `${Math.round(datum._y1)} mph`,
  ];
  const baseStyle = {
    fill: color.highlight,
    textAnchor: "middle",
  };
  const style = [
    {
      ...baseStyle,
      fontSize: 18,
      fontWeight: "bold",
    },
    { ...baseStyle, fontSize: 12 },
  ];

  return active ? (
    <VictoryLabel
      text={text}
      style={style}
      x={75}
      y={75}
      renderInPortal
    />
  ) : null;
}

function App() {
  const [state, setState] =
    React.useState({
      wind: getWindData(),
    });

  return (
    <VictoryChart
      polar
      animate={{
        duration: 500,
        onLoad: { duration: 500 },
      }}
      theme={VictoryTheme.clean}
      innerRadius={innerRadius}
      domainPadding={{ y: 10 }}
      events={[
        {
          childName: "all",
          target: "data",
          eventHandlers: {
            onMouseOver: () => {
              return [
                {
                  target: "labels",
                  mutation: () => ({
                    active: true,
                  }),
                },
                {
                  target: "data",
                  mutation: () => ({
                    active: true,
                  }),
                },
              ];
            },
            onMouseOut: () => {
              return [
                {
                  target: "labels",
                  mutation: () => ({
                    active: false,
                  }),
                },
                {
                  target: "data",
                  mutation: () => ({
                    active: false,
                  }),
                },
              ];
            },
          },
        },
      ]}
    >
      <VictoryPolarAxis
        dependentAxis
        labelPlacement="vertical"
        style={{
          axis: { stroke: "none" },
        }}
        tickFormat={() => ""}
      />
      <VictoryPolarAxis
        labelPlacement="parallel"
        tickValues={_.keys(
          directions,
        ).map((k) => +k)}
        tickFormat={_.values(
          directions,
        )}
      />
      <VictoryStack>
        <VictoryBar
          style={{
            data: {
              fill: ({ active }) =>
                active
                  ? orange.highlight
                  : orange.base,
              width: 40,
            },
          }}
          data={state.wind}
          x="windBearing"
          y="windSpeed"
          labels={() => ""}
          labelComponent={
            <CenterLabel
              color={orange}
            />
          }
        />
        <VictoryBar
          style={{
            data: {
              fill: (d, a) =>
                a
                  ? red.highlight
                  : red.base,
              width: 40,
            },
          }}
          data={state.wind}
          x="windBearing"
          y={(d) =>
            d.windGust - d.windSpeed
          }
          labels={() => ""}
          labelComponent={
            <CenterLabel color={red} />
          }
        />
      </VictoryStack>
      <CompassCenter />
    </VictoryChart>
  );
}

function getWindData() {
  return _.keys(directions).map((d) => {
    const speed =
      Math.floor(_.random() * 17) + 4;
    return {
      windSpeed: speed,
      windGust: speed + _.random(2, 10),
      windBearing: +d,
    };
  });
}

render(<App />);
```

## Standalone Rendering

Bar charts can be rendered outside a VictoryChart.

```jsx live
<VictoryBar
  theme={VictoryTheme.clean}
/>
```

They can also be embeded in other SVG components by using the `standalone` prop.

```jsx live
<div style={{ padding: "20px" }}>
  <svg
    width={300}
    height={300}
    style={{
      display: "block",
      margin: "0 auto",
    }}
  >
    <circle
      cx={150}
      cy={150}
      r={150}
      fill="#9ded91"
    />
    <VictoryBar
      standalone={false}
      theme={VictoryTheme.clean}
      width={300}
      height={300}
      padding={{ left: 10, right: 10 }}
      data={sampleData}
    />
  </svg>
</div>
```
